#ifndef _TASK_H
#define _TASK_H

#define THREAD_SIZE PAGE_SIZE
#define THREAD_SP   (THREAD_SIZE - 8)

#ifndef __ASSEMBLER__

#include "type.h"
#include "list.h"
#include "mmu.h"
#include "asm/processor.h"

#define MAX_TASK    128


typedef enum {
	TASK_RUNNING = 0,
	TASK_INTERRUPTIBLE = 1,
	TASK_UNINTERRUPTIBLE = 2,
	TASK_ZOMBIE = 3,
	TASK_STOPPED = 4,
} task_state;


typedef enum{
	PF_KTHREAD = 1 << 0,
    PF_UTHREAD = 1 << 1,
} task_flags;


struct task_struct{
    cpu_context     run_context;
    task_state      state;
    task_flags      flags;
    u64             pid;
    struct List     list_entry;
    u64             counter;
    u64             priority;
    u32             need_resched;
    u32             preempt_count;
    struct task_struct*    task_prev;
    struct task_struct*    task_next;
};


typedef union {
    struct task_struct tsk;
    u64         stack[THREAD_SIZE/sizeof(u64)];
} task_union;


#define DEF_COUNTER 100  /* 100ms time slice */


extern  task_union  init_task_union;
extern  struct task_struct*    g_tasks[];

#define init_task   (init_task_union.tsk)
#define INIT_TASK(tsk)  \
{   \
    .state      =   TASK_RUNNING,  \
    .flags      =   PF_KTHREAD,    \
    .pid        =   0,  \
    .counter    =   DEF_COUNTER,    \
    .priority   =   0,  \
    .need_resched   =   0,  \
    .preempt_count  =   0,  \
    .task_prev  =   &tsk,   \
    .task_next  =   &tsk,   \
    \
}


struct run_queue {
    struct List list_entry;
    u64 task_num;
};

extern struct run_queue rq;
void init_run_queue();

int find_empty_task();

void task01();
void task02();

#endif /* __ASSEMBLER__ */

#define THREAD_CPU_CONTEXT 0

#endif
